package com.hbwxz.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.Resource;

/**
 * 用户 Service
 *
 * @author shenzw
 * @date 2023/12/9
 */
@Service
@Slf4j
public class UserService {

    @Resource
    private JdbcTemplate jdbcTemplate;

    @Resource
    private PlatformTransactionManager transactionManager;

    @Resource
    private TransactionTemplate transactionTemplate;

    @Resource
    private UserService2 userService2;


    /////////////////////////////////////////////////  编程式事务【transactionManager】、【transactionTemplate】，缺点：入侵代码 /////////////////////////////////////////////////////////////

    /**
     * 转账例子 - 编程式事务演示【transactionManager】
     */
    public void transfer() {
        // 定义默认的事物属性
        DefaultTransactionDefinition defaultTransactionDefinition = new DefaultTransactionDefinition();

        // 获取 TransactionStatus
        TransactionStatus status = transactionManager.getTransaction(defaultTransactionDefinition);

        // 模拟转账
        try {
            jdbcTemplate.update("update user_tx set money = ? where id = ?", 2098, 1);
            int i = 1 / 0;
            transactionManager.commit(status);
        } catch (DataAccessException e) {
            transactionManager.rollback(status);
            throw new RuntimeException(e);
        }
    }

    /**
     * 转账例子 - 编程式事务演示【transactionTemplate】
     */
    public void trans2() {

        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                try {
                    jdbcTemplate.update("update user_tx set money = ? where user_name = ?", 20000, "张三");
                    int i = 1 / 0;
                } catch (DataAccessException e) {
                    transactionStatus.setRollbackOnly();
                    throw new RuntimeException(e);
                }
            }
        });
    }

    /**
     * 申明式事务 - 基于 XML配置（无侵入式）
     */
    @Transactional(transactionManager = "transactionManager")
    public void trans3() {
        jdbcTemplate.update("update user_tx set money = ? where id = ?", 1212, 1);
        try {
            userService2.trans();
        } catch (Exception e) {
            log.error("trans3 is error.", e);
        }
//        int i = 1 / 0;
    }

}
